import sys
import nmap
from .. import models


def scan_tools(sourceip, sourceport):
    scan_row = []
    input_data = sourceip + " " + sourceport
    # print(input_data)
    scan_row = input_data.split(" ")
    if len(scan_row) != 2:
        print("Input errors,example \"192.168.1.0/24 80,443,22\"")
        sys.exit(0)
    # 接收用户输入的主机
    hosts = scan_row[0]
    # 接收用户输入的端口
    port = scan_row[1]

    try:
        # 创建端口扫描对象
        nm = nmap.PortScanner()
    except nmap.PortScannerError:
        print('Nmap not found', sys.exc_info()[0])
        sys.exit(0)
    except:
        print("Unexpected error:", sys.exc_info()[0])
        sys.exit(0)

    try:
        # 调用扫描方法，参数指定扫描主机hosts，nmap扫描命令行参数arguments
        nm.scan(hosts=hosts, arguments=' -v -sS -p '+port)
    except Exception as e:
        print("Scan erro:"+str(e))

    # 刷选出IP地址是up状态的数据
    survivalData = []
    for host in nm.all_hosts():
        # 获取主机的状态
        if nm[host].state() == "up":
            # # 输出主机及主机名
            # host, nm[host].hostname())

            # 输出主机状态，如up、down
            # nm[host].state()

            for proto in nm[host].all_protocols():
                # 遍历扫描协议，如tcp、udp
                # 输入协议名 proto
                # 获取协议的所有扫描端口
                lport = nm[host][proto].keys()
                # 端口列表排序
                list(lport).sort()
                # 遍历端口及输出端口与状态
                for port in lport:
                    # 合并参数
                    port1 = host, nm[host].hostname(), nm[host].state(
                    ), proto, port, nm[host][proto][port]['state']
                    survivalData.append(port1)

    # 写入数据库,端口对应IP

    for i in survivalData:
        models.nmap_host.objects.get_or_create(host_ip=i[0], host_name=i[1],
                                               host_up=i[2], host_protocol=i[3], host_port=i[4], host_state=i[5])
    inactiveData = []
    for host in nm.all_hosts():
        # 主机状态非up状态
        if nm[host].state() != "up":
            # 输出主机及主机名
            # host, nm[host].hostname()))
            # 输出主机状态，如up、down
            # nm[host].state()
            # 合并参数
            inactiveTmp = host, nm[host].hostname(), nm[host].state()
            inactiveData.append(inactiveTmp)

    # 插入状态不是up的主机到数据库
    for i in inactiveData:
        models.nmap_host.objects.get_or_create(
            host_ip=i[0], host_name=i[1], host_up=i[2],)
